package com.xinz.serialization;

import java.util.ArrayList;
import java.util.HashMap;

public class StreamContext {

	static final int HEAD_EMPTY = 0;
	
	static final int HEAD_NULL = 1;
	
	static final int HEAD_NEW = 2;
	
	static final int HEAD_BASE = 3;
	
	static final int HEAD_REF = 4;
	
	static final ArrayList<Serialer> defaultIndexes = new ArrayList<Serialer>();
	
	ArrayList<Serialer> indexes = new ArrayList<Serialer>();
	ArrayList<Class<?>> classesList = new ArrayList<Class<?>>();
	
	HashMap<Class<?>, Serialer> simples = new HashMap<Class<?>, Serialer>(64);
	HashMap<Class<?>, Integer> classes = new HashMap<Class<?>, Integer>();
	
	public StreamContext() {
		for(Serialer serialer : defaultIndexes) {
			simples.put(serialer.getType(), serialer);
		}
	}
	
	static {
		addDefaultSerialer(new booleanSerialer());
		addDefaultSerialer(new PackSerialer.BooleanSerialer());
		
		addDefaultSerialer(new byteSerialer());
		addDefaultSerialer(new PackSerialer.ByteSerialer());

		addDefaultSerialer(new charSerialer());
		addDefaultSerialer(new PackSerialer.CharacterSerialer());
		
		addDefaultSerialer(new shortSerialer());
		addDefaultSerialer(new PackSerialer.ShortSerialer());
		
		addDefaultSerialer(new intSerialer());
		addDefaultSerialer(new PackSerialer.IntegerSerialer());
		
		addDefaultSerialer(new floatSerialer());
		addDefaultSerialer(new PackSerialer.FloatSerialer());
		
		addDefaultSerialer(new longSerialer());
		addDefaultSerialer(new PackSerialer.LongSerialer());
		
		addDefaultSerialer(new doubleSerialer());
		addDefaultSerialer(new PackSerialer.DoubleSerialer());
		
		addDefaultSerialer(new BaseObjectSerialer.StringSerialer());
		addDefaultSerialer(new BaseObjectSerialer.ArrayListSerialer());
		addDefaultSerialer(new objectArraySerialer());
	}
	
	private static  void addDefaultSerialer(Serialer serialer) {
		serialer.setIndex(true, defaultIndexes.size());
		defaultIndexes.add(serialer);
	}
	
	public void addClass(Class<?> clazz) {
		classes.put(clazz, Integer.valueOf(classesList.size()));
		classesList.add(clazz);
	}
	
	public void addSerialer(Serialer serialer) {
		serialer.setIndex(false, indexes.size());
		simples.put(serialer.getType(), serialer);
		indexes.add(serialer);
	}
	
	public Class<?> getClass(int index) {
		return classesList.get(index);
	}
	
	public Integer getClassIndex(Class<?> clazz) {
		return classes.get(clazz);
	}
	
	public Serialer getSerialer(Class<?> clazz) {
		return simples.get(clazz);
	}
	
	public Serialer getBase(int index) {
		return defaultIndexes.get(index);
	}
	
	public Serialer getDynamic(int id) {
		return indexes.get(id);
	}
}
